#ifndef _TLS_STATEM_H
#define _TLS_STATEM_H

#include "tls_connection.h"

typedef enum {
    TLS_ST_BEFORE,
    TLS_ST_CW_CLNT_HELLO,
    TLS_ST_CW_SUBJECT,
    TLS_ST_CW_KEY_SHARE,
    TLS_ST_CR_SRVR_HELLO,
    TLS_ST_CR_KEY_SHARE,
    TLS_ST_CR_CERT,
    TLS_ST_CR_SUBJECT,
    TLS_ST_CR_FINISHED,
    TLS_ST_CR_SIGN,
    TLS_ST_CW_CERT,
    TLS_ST_CW_FINISHED,
    TLS_ST_CW_SIGN,
    TLS_ST_SR_CLNT_HELLO,
    TLS_ST_SR_SUBJECT,
    TLS_ST_SR_KEY_SHARE,
    TLS_ST_SW_SRVR_HELLO,
    TLS_ST_SW_CERT,
    TLS_ST_SW_SUBJECT,
    TLS_ST_SW_KEY_SHARE,
    TLS_ST_SW_FINISHED,
    TLS_ST_SW_SIGN,
    TLS_ST_SR_CERT,
    TLS_ST_SR_FINISHED,
    TLS_ST_SR_SIGN,
    TLS_ST_OK
} SSL_HANDSHAKE_STATE;

int state_machine(int server);
typedef int (*handlefunc_f)(SSL_CONNECTION *s, PACKET *pkt);
int ssl_statem_client_handle_message(SSL_CONNECTION *s, handlefunc_f *func);
int ssl_statem_server_handle_message(SSL_CONNECTION *s, handlefunc_f *func);
int ssl_statem_client_transition(SSL_CONNECTION *s);
int ssl_statem_server_transition(SSL_CONNECTION *s);
int tls_construct_client_hello(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_client_certificate(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_client_subject(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_client_signature(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_server_hello(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_server_certificate(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_server_subject(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_finished(SSL_CONNECTION *s, PACKET *pkt);
int tls_construct_server_signature(SSL_CONNECTION *s, PACKET *pkt);

int tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_client_certificate(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_client_subject(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_client_signature(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_server_certificate(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_server_subject(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_server_signature(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt);
int tls_process_finished(SSL_CONNECTION *s, PACKET *pkt);

#endif 
